Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for reflect-filter list in avahi daemon. #62

Merged
merged 10 commits into from
Feb 13, 2020

Conversation

dkerr64
Copy link
Contributor

@dkerr64 dkerr64 commented Jul 2, 2016

This enhancement is provided courtesy of James Rudd James.Rudd@sbhs.nsw.edu.au and http://jrudd.org/2014/08/avahi-reflector-filtering-patch/

Allows avahi-daemon to filter which advertisements are added to the cache to be reflected to different networks. It checks incoming service names against a list defined in avahi-daemon.conf [reflector] reflect-filters. The list can be types of services or can contain hostnames to match.
For example if we only allow AirPlay and AirTunes to be reflected between VLANs, so have "_airplay._tcp.local,_raop._tcp.local" set. For AirPrint set "_printer._tcp.local,_ipp._tcp.local,_pdl-datastream._tcp.local"
Remember to set firewall rules to permit traffic between LANs for the corresponding ports.
The patch will block the PTR and SRV advertisements but will still allow A records for machine name lookup. All locally published services are still published even if they do not match the filter. The filter also blocks local programs from seeing advertised programs so it is recommend to only enable it on a dedicated bonjour reflector server. This has been tested on both ipv4 and ipv6.

This enhancement is provided courtesy of James Rudd <James.Rudd@sbhs.nsw.edu.au> and http://jrudd.org/2014/08/avahi-reflector-filtering-patch/

Allows Avahi-Daemon to  filter which advertisements are added to the cache to be reflected to different networks.
It checks incoming service names against a list defined  in avahi-daemon.conf [reflector] reflect-filters.
The list can be types of  services or can contain hostnames to match.
For example if we only allow AirPlay and AirTunes to be reflected between VLANs, so have  "_airplay._tcp.local,_raop._tcp.local" set.
For AirPrint set "_printer._tcp.local,_ipp._tcp.local,_pdl-datastream._tcp.local"
Remember to set firewall to permit traffic between LANs for the corresponding ports.

The patch will block the PTR and SRV advertisements but will still allow A records for machine name lookup.
All locally published services are still published even if they do not match the filter.

The filter also blocks local programs from seeing advertised programs so it is recommend to only enable it on a dedicated bonjour reflector server.
@abelbeck
Copy link

abelbeck commented Jul 2, 2016

I hope this PR gets accepted, we have been using James' patch in our project, adding very useful functionality. Kudos to James and @dkerr64 .

@ruddj
Copy link

ruddj commented Jul 3, 2016

Thanks for putting this all together David. Hopefully will be accepted into base.

…ed debug message for matches as well as rejects.

I have found that it is extremely useful to see what mDNS-SD messages are matched or rejected in order to debug
service discovery and therefore it is best if these messages can be turned on with the --debug flag as necessary.
@dkerr64
Copy link
Contributor Author

dkerr64 commented Jul 4, 2016

I thought I would document a printer use case for this enhancement.
If you have a WiFi guest VLAN and you want to permit guest devices to print or access a Apple TV then you need to enable mDNS-SD reflection and open firewall rules between the guest VLAN and the LAN on which the printers or Apple TV reside.

By default avahi-daemon will reflect all mDNS-SD messages which will potentially cause many more services to be broadcast onto the guest VLAN which is undesirable. This enhancement lets you control which services are published onto the guest VLAN so that e.g. only printing services are published.

For printers add the line...
reflect-filters=_printer._tcp.local,_ipp._tcp.local,_pdl-datastream._tcp.local
and now only printing services will be reflected into your guest VLAN.

This in itself is not enough, you must also open up firewall ports to allow traffic from guest VLAN to the IP address of the printer(s). With iptables this would look like...

-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.8/32 -p tcp -m tcp --dport 515 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.8/32 -p tcp -m tcp --dport 631 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.8/32 -p tcp -m tcp --dport 9100 -j ACCEPT

Where 192.168.101.0/24 is guest network and 192.168.1.8 is IP address of printer on your main LAN.

A similar method can be used to enable access to AirPlay devices, though the firewall rules are more complex.

David

@dkerr64
Copy link
Contributor Author

dkerr64 commented Jul 4, 2016

As mentioned in my previous comment, AirPlay can also be enabled across LANs. In this example I have tested using the AirServer application on a Apple Mac, not with a genuine Apple TV. Different rules may be required for a genuine Apple TV.

In avahi-daemon.conf...
reflect-filters=_airplay._tcp.local,_raop._tcp.local,_device-info._tcp.local

Firewall iptables rules...

-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 5001 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 7000 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 7001 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 49152 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p udp -m udp --dport 6010 -j ACCEPT
-A <your forward chain> -s 192.168.101.0/24 -d 192.168.1.5/32 -p udp -m udp --dport 6011 -j ACCEPT
-A <your forward chain> -s 192.168.1.5/32 -d 192.168.101.0/24 -p udp -m udp --sport 6012 -j ACCEPT

Where 192.168.101.0/24 is guest network and 192.168.1.5 is IP address of Mac running AirServer on your main LAN.

Note, ports may be different for a real Apple TV or other AirPlay device (e.g. a AirPlay speaker) or any other mDNS-SD You can use tcpdump to identify them. You can also run avahi-daemon --debug to see which mDNS-SD messages are getting reflected or rejected, this can be helpful when initially setting up a new device to be reflected.

David

@lathiat
Copy link
Contributor

lathiat commented Jul 5, 2016

Thanks for your contribution, and testing reports. I would be happy to include this once I've reviewed it.

I noticed at WWDC that Apple added support for Bluetooth beacons to show or highlight nearby printers from Bonjour.. I desperately hope they add this for airplay targets as well.

…disable-publishing=yes

is set in conf file.  Fixes lathiat/avahi issue avahi#38
@dkerr64
Copy link
Contributor Author

dkerr64 commented Feb 25, 2017

@lathiat any chance we can have this merged into the master please? We have been running this in production on astlinux (http://www.astlinux-project.org/) for close to 9 months now without problems. Thanks

@dkerr64
Copy link
Contributor Author

dkerr64 commented Mar 21, 2017

@lathiat Can you please review this pull request and comment or merge into the master please.
Thank you

@dkerr64
Copy link
Contributor Author

dkerr64 commented Aug 15, 2017

@lathiat Can you please review this pull request and comment or merge into the master please.Thank you

@c-po
Copy link

c-po commented Sep 18, 2017

Sounds like a really good enhancement to Avahi. Thank you!

@dkerr64
Copy link
Contributor Author

dkerr64 commented Sep 18, 2017

Thank you. I just wish @lathiat would merge into master.

agitelzon pushed a commit to APMG/puppet-avahi that referenced this pull request Aug 7, 2018
@cpoetter
Copy link

I am looking for exactly this! I hope it gets merged soon.

@cpoetter
Copy link

cpoetter commented Apr 6, 2019

@lathiat Could you please merge @dkerr64's awesome pull request?

@cpoetter
Copy link

cpoetter commented Apr 17, 2019

@dkerr64 I build from source with your patch and ran it, but unfortunately it is still reflecting all services, not only the once allowed with reflect-filters. I uncommented the example line you provided in the avahi config file for my testing:

reflect-filters=_airplay._tcp.local,_raop._tcp.local

These are the steps I took to build from source:

autoreconf -i
autoconf configure.ac
./configure --prefix=/usr        \
            --sysconfdir=/etc    \
            --localstatedir=/var \
            --disable-mono       \
            --disable-python     \
            --disable-qt5 
make
sudo make install

Did I do something wrong?

@dkerr64
Copy link
Contributor Author

dkerr64 commented Apr 21, 2019

Chris @cpoetter, thanks for posting your question. I tested on my network today and it is working as expected. I assume you have two networks (e.g. 192.168.1.0/24 and 192.168.2.0/24) and that avahi is running on a box that is connected to both? My conf file includes this section...

[reflector]
enable-reflector=yes
reflect-ipv=no
reflect-filters=_printer._tcp.local,_ipp._tcp.local,_pdl-datastream._tcp.local,_airplay._tcp.local,_raop._tcp.local,_device-info._tcp.local,_googlecast._tcp.local,_googlerpc._tcp.local,_googlezone._tcp.local

And I confirmed by connecting an iPhone to one network and using the Discovery app (https://itunes.apple.com/us/app/discovery-dns-sd-browser/id305441017?mt=8) and it only showed those devices from the other network that broadcast one of the above tags. If I comment out the reflect-filters statement and restart the daemon then dozens of Bonjour/DNS-SD names are visible.

David.

@dkerr64
Copy link
Contributor Author

dkerr64 commented Apr 21, 2019

Chris @cpoetter, I should add that some devices, including iPhones/iPads/Macs cache Bonjour/DNS-SD replies.. so if you start out testing by reflecting everything, then change to a selective list, then that device will still have in its cache the full list. I don't know how long it takes for the cache to flush.
David

wisd0me and others added 5 commits September 25, 2019 15:38
This commit fixes the bug, when there is multiple records in the
response (usually there are), and first record does not correspond to
any of the configured services - originally, packet was getting dropped.
With this fix current record is skipped, and the code looks further.
@dkerr64
Copy link
Contributor Author

dkerr64 commented Sep 26, 2019

@wisd0me found a memory leak in the filter which he fixed. That prompted me to look at the file and I found another instance of the same leak so I added fix for that. Once again I ask @lathiat to please merge this pull request or at least comment on this thread.

@x1ddos
Copy link

x1ddos commented Dec 1, 2019

I suggest splitting this pull request and moving the avahi-core/iface.c change which suppresses the spurious log messages into a separate PR. It has nothing to do with the feature being introduced here and will have better chances to get merged, IMHO.

@dkerr64
Copy link
Contributor Author

dkerr64 commented Dec 1, 2019

I suggest splitting this pull request and moving the avahi-core/iface.c change which suppresses the spurious log messages into a separate PR. It has nothing to do with the feature being introduced here and will have better chances to get merged, IMHO.

As this PR has been siting here for over 3 years without comment from @lathiat I doubt there is very much I could do short of appealing to him yet again to consider merging this. I will await his guidance.

@lathiat lathiat merged commit 36748a4 into avahi:master Feb 13, 2020
@lathiat lathiat added this to the v0.8 milestone Feb 13, 2020
@dkerr64
Copy link
Contributor Author

dkerr64 commented Feb 13, 2020

THANK YOU @lathiat

@josephallix
Copy link

Please excuse my ignorance but how do I apply this patch to my current Avahi running on Ubuntu 16..04?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants